package cn.dengta.webapp.user.entity.task;

import java.io.Serializable;

import cn.dengta.common.model.Status;
import cn.dengta.webapp.user.model.GiftType;
import lombok.Getter;
import lombok.Setter;
import me.codeplayer.util.*;

/**
 * 签到活动的规则配置对象
 */
@Getter
@Setter
public class SignRuleConfig implements RuleConfig {

	private static final long serialVersionUID = 1L;
	//
	/** 周期：0=连续；1=循环 */
	Integer mode;
	protected SignConfigEntry[] entries;

	@Override
	public void validate() {
		Assert.isTrue(X.size(entries) == 7, "配置必须设置7天！");
		for (int i = entries.length - 1; i > 0; ) {
			SignConfigEntry entry = entries[i--];
			entry.validate();
			SignConfigEntry nextEntry = entries[i];
			entry.validate();
			Assert.isTrue(entry.day > nextEntry.day, "签到天数只能递增！");
			Assert.isTrue(entry.day > nextEntry.day, "签到天数只能递增！");
		}
	}

	@Override
	public void init(RuleConfig config) {
		SignRuleConfig pointConfig = (SignRuleConfig) config;
		this.entries = pointConfig.entries;
	}

	public SignConfigEntry getEntry(Integer times, boolean defaultValue) {
		for (int i = entries.length - 1; i >= 0; i--) {
			if (times >= entries[i].day) {
				return entries[i];
			}
		}
		return defaultValue ? entries[0] : null;
	}

	public boolean cyclic() {
		return Status.asResult(mode);
	}

	public int calcDay(int day) {
		if (cyclic()) {
			day = day % entries.length;
			if (day == 0) {
				day = entries.length;
			}
		}
		return day;
	}

	@Override
	public boolean clearCoin() {
		return true;
	}

	@Override
	public Integer getMin() {
		return 0;
	}

	/**
	 * 签到活动规则实体
	 */
	@Setter
	@Getter
	public static class SignConfigEntry implements Serializable {

		/** 类型 {@link GiftType} */
		protected Integer type;
		/** 签到天数 */
		protected Integer day;
		/** 时长（分）或者钻石 */
		protected Integer price;
		/** 数量 */
		protected Integer count;
		/** 有效天数 */
		protected Integer validDay;

		public SignConfigEntry(Integer type, Integer day, Integer price, Integer validDay, Integer count) {
			this.type = type;
			this.day = day;
			this.price = price;
			this.validDay = validDay;
			this.count = count;
		}

		public void validate() {
			final GiftType giftType = GiftType.of(type);
			Assert.isTrue(giftType != null, "请选择类型！");
			Assert.isTrue(day > 0, "签到天数必须大于0！");
			switch (giftType) {
				case COIN: // 钻石
					Assert.isTrue(price > 0, "钻石必须大于0！");
					validDay = null;
					break;
				case VIDEO: // 视频卡
				case AUDIO: // 语音卡
					Assert.isTrue(price > 0, "时长必须大于0！");
				case VIP: // vip
					if (giftType == GiftType.VIP) {
						price = null;
					}
					Assert.isTrue(validDay > 0, "有效期必须大于0！");
					break;
				default:
					throw new IllegalArgumentException();
			}
			count = 1; // 目前默认所有数量都是1
		}

		public static Integer signNum(SignConfigEntry input) {
			Integer num = 0;
			if (input == null) {
				return num;
			}
			final GiftType giftType = GiftType.of(input.getType());
			switch (giftType) {
				case COIN: // 钻石
					num = input.getPrice();
					break;
				case VIDEO: // 视频卡
				case AUDIO: // 语音卡
				case VIP: // vip
					num = NumberUtil.getInt(input.getCount(), 1);
					break;
			}
			return num;
		}

		public String getTypeLabel() {
			return X.map(GiftType.of(type), GiftType::getLabel);
		}

		public String getIcon() {
			return X.map(GiftType.of(type), GiftType::getIcon);
		}

	}

}
